package eabnp.service;

import eabnp.basic.propertiesfile.EPropertiesFile;
import eabnp.basic.result.GResult;
import eabnp.basic.result.IResult;
import eabnp.basic.result.SGResult;
import eabnp.basic.result.SimpleResult;
import eabnp.basic.util.ClassUtil;
import eabnp.basic.util.StringUtil;
import eabnp.basic.util.SystemEnv;
import eabnp.basic.util.array.ArrayUtil;
import eabnp.service.elog.ELog;
import eabnp.service.elog.ILogger;
import eabnp.service.evar.EVarManager;
import java.util.HashMap;
import java.util.Map;

public final class ServiceManager {

	public static final String EABNP_NAME_SEPARATOR = ".";
	public static final String EABNP_CONFIG_SEPARATOR = ";";
	public static final String EABNP_ENV_VARNAME_PATH_PREFIX = "Path:";
	public static final String EABNP_PATH_PARANAME = "EABnPPath";
	public static final String EABNP_DEFAULT_PATH =getConfigFilePath();
	public static final String BASIC_CONFIG_FILENAME = "eabnp.properties";
	public static final String EVAR_XML_FILENAME = "evar.xml";
	public static final String EFLOW_SERVICE_NAME = "EFlow";
	public static final String EFLOW_DEFAULT_CLASS = "eabnp.eflow.EFlow";
	public static final String EABNP_SERVICE_PACKAGE = ServiceManager.class.getPackage().getName();
	public static final String EABNP_SERVICE_INSTANCE_GETMETHOD = "getInstance";
	public static final String PROPERTY_NAME_SERVERNAME = "ServerName";
	private static final ServiceManager instance = new ServiceManager();
	private String serverName;
	private boolean active = false;
	private String rootPath = EABNP_DEFAULT_PATH;

	private String configFileName = EABNP_DEFAULT_PATH + SystemEnv.FILE_SEPARATOR + "eabnp.properties";
	private EPropertiesFile propertiesFile = null;
	private Map<String, IService> servicesMap = null;

	private String evarXmlFileName = EABNP_DEFAULT_PATH + SystemEnv.FILE_SEPARATOR + "evar.xml";
	private EVarManager evarManager = null;

	public EVarManager getEvarManager() {
		return this.evarManager;
	}

	private ServiceManager() {
		this.servicesMap = new HashMap();
	}

	public static ServiceManager getInstance() {
		return instance;
	}

	public static String getServerNameofService(String serviceName) {
		return null;
	}

	public static String getLocalServerName() {
		return instance.serverName;
	}

	public static String getAbsolutePath(String path) {
		String p;
		if (SystemEnv.IS_WINDOWS)
			p = path.replaceAll("/", "\\");
		else {
			p = path.replaceAll("\\\\", "/");
		}

		if (p.indexOf("{$") == -1) {
			return p;
		}

		return p;
	}

	private static String getServiceDefaultClassName(String serviceName) {
		if ("EFlow".equals(serviceName)) {
			return "eabnp.eflow.EFlow";
		}

		return EABNP_SERVICE_PACKAGE + "." + serviceName.toLowerCase() + "." + serviceName;
	}

	private static GResult getServiceInstance(String serviceName) {
		String str = getProperty(serviceName + ".Class", getServiceDefaultClassName(serviceName));

		GResult r = ClassUtil.getInstanceOfClass(str, "getInstance", null, null);
		if (r.isFailure()) {
			r.addErrMsgPreStr("获取服务管理器实例失败");
			return r;
		}

		if (!ClassUtil.isInterfaceImplents(r.getResultObject().getClass(), IService.class.getName())) {
			return GResult.newFailureResult("服务" + serviceName + "的管理类" + str + "没有实现IBasicService接口");
		}

		Class c = null;
		try {
			c = Class.forName(str);
		} catch (ClassNotFoundException ex) {
			return GResult.newFailureResult(null, "找不到服务" + serviceName + "的管理类：" + str, ex);
		}

		if (!ClassUtil.isInterfaceImplents(c, IService.class.getName())) {
			return GResult.newFailureResult("服务" + serviceName + "的管理类" + str + "没有实现IBasicService接口");
		}

		return r;
	}

	public static IResult start() {
		ELog.getSysOutLogger().logSysInfo("");
		ELog.getSysOutLogger().logSysInfo("");
		ELog.getSysOutLogger().logSysInfo("*************TRiFID EABnP : 北京远信 Enterprise Application Builder and Platform*************");

		ELog.getSysOutLogger().logSysInfo("");
		ELog.getSysOutLogger().logSysInfo("");
		ELog.getSysOutLogger().logSysInfo("EABnP基本服务管理器开始启动");
		ELog.getSysOutLogger().logSysInfo("EABnP当前版本：1.0");

		instance.servicesMap.clear();
		try {
			instance.propertiesFile = new EPropertiesFile(instance.configFileName, true);
		} catch (Exception ex) {
			String msg = "EABnP基本服务管理器无法启动，读取EABnP配置文件失败：" + ex.getMessage();
			return ELog.getSysOutLogger().logErrAndGenerateResult(msg, ex);
		}

		instance.serverName = instance.propertiesFile.getProperty("ServerName");

		ELog.getSysOutLogger().logSysInfo("");
		ELog.getSysOutLogger().logSysInfo("开始启动服务ELog");
		ELog.getInstance().startService(false);
		instance.servicesMap.put(ELog.getInstance().getName(), ELog.getInstance());

		ELog.getLogger().logSysInfo("");
		ELog.getLogger().logSysInfo("开始解析环境变量");
		instance.evarManager = new EVarManager(instance.evarXmlFileName);
		try {
			instance.evarManager.parseEVarXml();
		} catch (Exception ex) {
			ex.printStackTrace();
			GResult gr = GResult.newFailureResult("解析环境变量失败", ex);
			ELog.getLogger().logErr(gr);
			return gr;
		}
		ELog.getLogger().logSysInfo("解析环境变量完成");

		String str = getProperty("Service", "");
		if (!StringUtil.isNullOrEmptyStr(str)) {
			String[] sa = str.split(";");
			int l = ArrayUtil.getArraySize(sa);
			for (int i = 0; i < l; i++) {
				String s = sa[i].trim();
				if (!StringUtil.isNullOrEmptyStr(s)) {
					ELog.getLogger().logSysInfo("");
					ELog.getLogger().logSysInfo("开始启动服务" + s);

					GResult gr = getServiceInstance(s);
					if (gr.isFailure()) {
						gr.addErrMsgPreStr("服务" + s + "启动失败");
						ELog.getLogger().logErr(gr);
					} else {
						IService bs = (IService) gr.getResultObject();
						IResult r = bs.startService(false);
						if (r.isFailure()) {
							r.addErrMsgToIResult("服务" + s + "启动失败");
							ELog.getLogger().logErr(r);
						}
						instance.servicesMap.put(bs.getName(), bs);
					}
				}
			}
		}

		ELog.getLogger().logSysInfo("");
		ELog.getLogger().logSysInfo("EABnP基本服务管理器启动完毕");
		ELog.getLogger().logSysInfo("");

		return SimpleResult.SUCCESS;
	}

	private void setRootPath(String eabnpPath) {
		if (StringUtil.isNullOrEmptyStr(eabnpPath))
			return;

		this.rootPath = eabnpPath;
		this.configFileName = (this.rootPath + SystemEnv.FILE_SEPARATOR + "eabnp.properties");
		this.evarXmlFileName = (this.rootPath + SystemEnv.FILE_SEPARATOR + "evar.xml");
	}

	public static IResult start(String rootPath) {
		instance.setRootPath(rootPath);

		return start();
	}

	public static IResult stop() {
		return null;
	}

	public static IService getService(String serviceName) {
		return null;
	}

	public static IResult startService(String serviceName, boolean force) {
		IService s = getService(serviceName);
		return s.startService(force);
	}

	public static IResult stopService(String serviceName, boolean force) {
		IService s = getService(serviceName);
		return s.stopService(force);
	}

	public static String getProperty(String propertyName, String defaultValue) {
		return instance.propertiesFile.getProperty(propertyName, defaultValue);
	}

	public static String getProperty(String propertyName) {
		return instance.propertiesFile.getProperty(propertyName);
	}

	public static ILogger getLogger() {
		return ELog.getLogger();
	}

	public static ILogger getLogger(String loggerName) {
		return ELog.getLogger(loggerName);
	}

	public static String getRootPath() {
		return instance.rootPath;
	}

	public static boolean isActive() {
		return instance.active;
	}

	public static SGResult createEVarClass(String name) {
		try {
			instance.evarManager.createEVarClass(name);
		} catch (Exception ex) {
			ex.printStackTrace();
			return SGResult.newFailureResult(ex.getMessage());
		}

		return SGResult.newSuccessResult();
	}

	public static SGResult delEVarClass(String name) {
		try {
			instance.evarManager.delEVarClass(name);
		} catch (Exception ex) {
			ex.printStackTrace();
			return SGResult.newFailureResult(ex.getMessage());
		}

		return SGResult.newSuccessResult();
	}

	public static SGResult setEVar(String className, String code, String value, int sn, String desc) {
		try {
			instance.evarManager.setEVar(className, code, value, sn, desc);
		} catch (Exception ex) {
			ex.printStackTrace();
			return SGResult.newFailureResult(ex.getMessage());
		}

		return SGResult.newSuccessResult();
	}

	public static SGResult delEVar(String className, String code) {
		try {
			instance.evarManager.delEVar(className, code);
		} catch (Exception ex) {
			ex.printStackTrace();
			return SGResult.newFailureResult(ex.getMessage());
		}

		return SGResult.newSuccessResult();
	}

	public static String getEVarXml() {
		return instance.evarManager.toXmlString();
	}

	public static String getEVarString(String className, String code) {
		return instance.evarManager.getEVarString(className, code);
	}
	
	public static String getConfigFilePath(){
		return Thread.currentThread().getContextClassLoader().getResource("../../").getPath()+"eabnp/";
	}
}
